home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / PASCAL / FPKPAS65.ZIP / SRCRTLDO.ZIP / SOURCE / RTL / DOS / DOS.PP < prev    next >
Encoding:
Text File  |  1996-07-23  |  18.0 KB  |  736 lines

  1. {****************************************************************************
  2.  
  3.                           FPKPascal Runtime-Library
  4.                           Copyright (c) 1993,95 by
  5.                               Florian Klämpfl
  6.  
  7.  ****************************************************************************}
  8.  
  9. {
  10.   History:
  11.   2.7.1994: Version 0.2
  12.             Datenstrukturen sind deklariert sowie
  13.             50 % der Unterprogramme sind implementiert
  14.   12.8.1994: EXEC implementiert
  15.   14.8.1994: FINDFIRST und FINDNEXT implementiert
  16.   24.8.1994: Version 0.3
  17.   28.2.1995: Version 0.31
  18.              verschiedene Prozeduraufrufe durch Einsatz von const optimiert
  19.    3.7.1996: bug in fsplit removed (dir and ext were not intializised)
  20.    7.7.1996: packtime and unpacktime implemented
  21. }
  22.  
  23. unit dos;
  24.  
  25. {$E-}
  26.  
  27.   interface
  28.  
  29.     uses
  30.        strings;
  31.  
  32.     const
  33.        { bit masks for CPU flags}
  34.        fcarry = $0001;
  35.        fparity = $0004;
  36.        fauxiliary = $0010;
  37.        fzero = $0040;
  38.        fsign = $0080;
  39.        foverflow  = $0800;
  40.  
  41.        { Bitmasken fuer Dateiattribute }
  42.        readonly = $01;
  43.        hidden = $02;
  44.        sysfile = $04;
  45.        volumeid = $08;
  46.        directory = $10;
  47.        archive = $20;
  48.        anyfile = $3F;
  49.        fmclosed = $D7B0;
  50.        fminput = $D7B1;
  51.        fmoutput = $D7B2;
  52.        fminout = $D7B3;
  53.  
  54.     type
  55.        { verschiedene Stringtypen }
  56.        comstr = string[127];        { Kommandozeilenstring }
  57.        pathstr = string[79];        { String fuer einen Pfadnamen }
  58.        dirstr = string[67];         { String fuer kompletten Pfad }
  59.        namestr = string[8];         { Dateinamenstring }
  60.        extstr = string[4];          { String fuer Dateinamensuffix }
  61.  
  62.        { Suchrecords, die von findfirst und findnext benutzt werden }
  63. {$PACKRECORDS 1}
  64.        searchrec = record
  65.           fill : array[1..21] of byte;
  66.           attr : byte;
  67.           time : longint;
  68.           size : longint;
  69.           reserved : word; { verlangt (DJ GNU-C) }
  70.              { bis ich das herausgefunden hatte... }
  71.           name : string[12];
  72.              { könnte auch als string[15] deklariert werden (DJ GNU-C) }
  73.        end;
  74. {$PACKRECORDS 2}
  75.        { Dateirecord für typisierte und untypsierte Dateien }
  76.  
  77.        filerec = record
  78.           handle : word;
  79.           mode : word;
  80.           recsize : word;
  81.           _private : array[1..26] of byte;
  82.           userdata: array[1..16] of byte;
  83.           name: array[0..79] of char;
  84.        end;
  85.  
  86.        { Dateirecord fuer Textdateien }
  87.  
  88.        textbuf = array[0..127] of char;
  89.  
  90.        textrec = record
  91.           handle : word;
  92.           mode : word;
  93.           bufSize : word;
  94.           _private : word;
  95.           bufpos : word;
  96.           bufend : word;
  97.           bufptr : ^textbuf;
  98.           openfunc : pointer;
  99.           inoutfunc : pointer;
  100.           flushfunc : pointer;
  101.           closefunc : pointer;
  102.           userdata : array[1..16] of byte;
  103.           name : array[0..79] of char;
  104.           buffer : textbuf;
  105.        end;
  106.  
  107.        { Record welcher von Intr und msdos verwendet werden }
  108.  
  109.        registers = record
  110.          case i : integer of
  111.             0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  112.             1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  113.             2 : (eax,  ebx,  ecx,  edx,  ebp,  esi,  edi : longint);
  114.        end;
  115.  
  116.        { Record fuer Zeit und Datum }
  117.  
  118.        datetime = record
  119.           year,month,day,hour,min,sec : word;
  120.        end;
  121.  
  122.     var
  123.        { Fehlervariable }
  124.        doserror : integer;
  125.  
  126.     procedure getdate(var year,month,day,dayofweek : word);
  127.     procedure gettime(var hour,minute,second,sec100 : word);
  128.     function dosversion : word;
  129.     procedure setdate(year,month,day : word);
  130.     procedure settime(hour,minute,second,sec100 : word);
  131.     procedure getcbreak(var breakvalue : boolean);
  132.     procedure setcbreak(breakvalue : boolean);
  133.     procedure getverify(var verify : boolean);
  134.     procedure setverify(verify : boolean);
  135.     function diskfree(drive : byte) : longint;
  136.     function disksize(drive : byte) : longint;
  137.     procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  138.     procedure findnext(var f : searchRec);
  139.  
  140.     { Dummy }
  141.     procedure swapvectors;
  142.  
  143. {   Nicht unterstützt:
  144.  
  145.     procedure msdos(var regs : registers);
  146.     procedure getintvec(intno : byte;var vector : pointer);
  147.     procedure setintvec(intno : byte;vector : pointer);
  148.     procedure keep(exitcode : word);
  149. }
  150.     procedure intr(intno : byte;var regs : registers);
  151.  
  152. { Noch zu implementieren:
  153.     procedure getfattr(var f;var attr : word);
  154.     procedure setfattr(var f;attr : word);
  155.     procedure getftime(var f;var time : longint);
  156.     procedure setftime(var f;time : longint);
  157.     function fsearch(path : pathstr;dirlist : string) : pathstr;
  158.  
  159. }
  160.     procedure packtime (var d: datetime; var time: longint);
  161.     procedure unpacktime (time: longint; var d: datetime);
  162.     function fexpand(const path : pathstr) : pathstr;
  163.     procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;
  164.       var ext : extstr);
  165.     procedure exec(const path : pathstr;const comline : comstr);
  166.     function dosexitcode : word;
  167.     function envcount : integer;
  168.     function envstr(index : integer) : string;
  169.     function getenv(const envvar : string): string;
  170.  
  171.   implementation
  172.  
  173.     procedure intr(intno : byte;var regs : registers);
  174.  
  175.       begin
  176.          asm
  177.             .data
  178.     int86:
  179.             .byte        0xcd
  180.     int86_vec:
  181.             .byte        0x03
  182.             jmp        int86_retjmp
  183.  
  184.             .text
  185.             movl        8(%ebp),%eax
  186.             movb        %al,int86_vec
  187.  
  188.             movl        10(%ebp),%eax
  189.             // do not use first int
  190.             addl        $2,%eax
  191.  
  192.             movl        4(%eax),%ebx
  193.             movl        8(%eax),%ecx
  194.             movl        12(%eax),%edx
  195.             movl        16(%eax),%ebp
  196.             movl        20(%eax),%esi
  197.             movl        24(%eax),%edi
  198.             movl        (%eax),%eax
  199.  
  200.             jmp        int86
  201.     int86_retjmp:
  202.             pushf
  203.             pushl    %ebp
  204.             pushl       %eax
  205.             movl        %esp,%ebp
  206.             // calc EBP new
  207.             addl        $12,%ebp
  208.             movl        10(%ebp),%eax
  209.             // do not use first int
  210.             addl        $2,%eax
  211.  
  212.             popl        (%eax)
  213.             movl        %ebx,4(%eax)
  214.             movl        %ecx,8(%eax)
  215.             movl        %edx,12(%eax)
  216.             // restore EBP
  217.             popl    %edx
  218.             movl    %edx,16(%eax)
  219.             movl        %esi,20(%eax)
  220.             movl        %edi,24(%eax)
  221.             // ignore ES and DS
  222.             popl        %ebx        /* flags */
  223.             movl        %ebx,32(%eax)
  224.             // FS and GS too
  225.          end;
  226.       end;
  227.  
  228.     var
  229.        lastdosexitcode : word;
  230.  
  231.     procedure exec(const path : pathstr;const comline : comstr);
  232.  
  233.       procedure do_system(p : pchar);
  234.  
  235.         begin
  236.            asm
  237.               movl 12(%ebp),%ebx
  238.               movw $0xff07,%ax
  239.               int $0x21
  240.               movw %ax,_LASTDOSEXITCODE
  241.            end;
  242.         end;
  243.  
  244.       var
  245.          execute : string;
  246.          b : array[0..255] of char;
  247.  
  248.       begin
  249.          execute:=path+' '+comline;
  250.          move(execute[1],b,length(execute));
  251.          b[length(execute)]:=#0;
  252.          do_system(b);
  253.       end;
  254.  
  255.     function dosexitcode : word;
  256.  
  257.       begin
  258.          dosexitcode:=lastdosexitcode;
  259.       end;
  260.  
  261.     function dosversion : word;
  262.  
  263.       begin
  264.          asm
  265.             movb $0x30,%ah
  266.             pushl %ebp
  267.             int $0x21
  268.             popl %ebp
  269.             leave
  270.             ret
  271.          end;
  272.       end;
  273.  
  274.     procedure getdate(var year,month,day,dayofweek : word);
  275.  
  276.       begin
  277.          asm
  278.             movb $0x2a,%ah
  279.             pushl %ebp
  280.             int $0x21
  281.             popl %ebp
  282.             xorb %ah,%ah
  283.             movl 20(%ebp),%edi
  284.             stosw
  285.             movl 16(%ebp),%edi
  286.             movb %dl,%al
  287.             stosw
  288.             movl 12(%ebp),%edi
  289.             movb %dh,%al
  290.             stosw
  291.             movl 8(%ebp),%edi
  292.             movw %cx,%ax
  293.             stosw
  294.          end;
  295.       end;
  296.  
  297.     procedure setdate(year,month,day : word);
  298.  
  299.       begin
  300.          asm
  301.             movw 8(%ebp),%cx
  302.             movb 10(%ebp),%dh
  303.             movb 12(%ebp),%dl
  304.             movb $0x2b,%ah
  305.             pushl %ebp
  306.             int $0x21
  307.             popl %ebp
  308.             xorb %ah,%ah
  309.             movw %ax,U_DOS_DOSERROR
  310.          end;
  311.       end;
  312.  
  313.     procedure gettime(var hour,minute,second,sec100 : word);
  314.  
  315.       begin
  316.          asm
  317.             movb $0x2c,%ah
  318.             pushl %ebp
  319.             int $0x21
  320.             popl %ebp
  321.             xorb %ah,%ah
  322.             movl 20(%ebp),%edi
  323.             movb %dl,%al
  324.             stosw
  325.             movl 16(%ebp),%edi
  326.             movb %dh,%al
  327.             stosw
  328.             movl 12(%ebp),%edi
  329.             movb %cl,%al
  330.             stosw
  331.             movl 8(%ebp),%edi
  332.             movb %ch,%al
  333.             stosw
  334.          end;
  335.       end;
  336.  
  337.     procedure settime(hour,minute,second,sec100 : word);
  338.  
  339.       begin
  340.          asm
  341.             movb 8(%ebp),%ch
  342.             movb 10(%ebp),%cl
  343.             movb 12(%ebp),%dh
  344.             movb 14(%ebp),%dl
  345.             movb $0x2d,%ah
  346.             pushl %ebp
  347.             int $0x21
  348.             popl %ebp
  349.             xorb %ah,%ah
  350.             movw %ax,U_DOS_DOSERROR
  351.          end;
  352.       end;
  353.  
  354.     procedure getcbreak(var breakvalue : boolean);
  355.  
  356.       begin
  357.          asm
  358.             movw $0x3300,%ax
  359.             pushl %ebp
  360.             int $0x21
  361.             popl %ebp
  362.             movl 8(%ebp),%eax
  363.             movb %dl,(%eax)
  364.          end;
  365.       end;
  366.  
  367.     procedure setcbreak(breakvalue : boolean);
  368.  
  369.       begin
  370.          asm
  371.             movb 8(%ebp),%dl
  372.             movl $0x3301,%ax
  373.             pushl %ebp
  374.             int $0x21
  375.             popl %ebp
  376.          end;
  377.       end;
  378.  
  379.     procedure getverify(var verify : boolean);
  380.  
  381.       begin
  382.          asm
  383.             movb $0x54,%ah
  384.             pushl %ebp
  385.             int $0x21
  386.             popl %ebp
  387.             movl 8(%ebp),%edi
  388.             stosb
  389.          end;
  390.       end;
  391.  
  392.     procedure setverify(verify : boolean);
  393.  
  394.       begin
  395.          asm
  396.             movb 8(%ebp),%al
  397.             movl $0x2e,%ah
  398.             pushl %ebp
  399.             int $0x21
  400.             popl %ebp
  401.          end;
  402.       end;
  403.  
  404.     function diskfree(drive : byte) : longint;
  405.  
  406.       begin
  407.          asm
  408.             movb 8(%ebp),%dl
  409.             movb $0x36,%ah
  410.             pushl %ebp
  411.             int $0x21
  412.             popl %ebp
  413.             cmpw $-1,%ax
  414.             je LDISKFREE1
  415.             mulw %cx
  416.             mulw %bx
  417.             shll $16,%edx
  418.             movw %ax,%dx
  419.             movl %edx,%eax
  420.             leave
  421.             ret
  422.          LDISKFREE1:
  423.             movl $-1,%eax
  424.             leave
  425.             ret
  426.          end;
  427.       end;
  428.  
  429.     function disksize(drive : byte) : longint;
  430.  
  431.       begin
  432.          asm
  433.             movb 8(%ebp),%dl
  434.             movb $0x36,%ah
  435.             pushl %ebp
  436.             int $0x21
  437.             popl %ebp
  438.             movw %dx,%bx
  439.             cmpw $-1,%ax
  440.             je LDISKSIZE1
  441.             mulw %cx
  442.             mulw %bx
  443.             shll $16,%edx
  444.             movw %ax,%dx
  445.             movl %edx,%eax
  446.             leave
  447.             ret
  448.          LDISKSIZE1:
  449.             movl $-1,%eax
  450.             leave
  451.             ret
  452.          end;
  453.       end;
  454.  
  455.     procedure searchrec2dossearchrec(var f : searchrec);
  456.  
  457.       var
  458.          l,i : longint;
  459.  
  460.       begin
  461.          l:=length(f.name);
  462.          for i:=1 to 12 do
  463.            f.name[i-1]:=f.name[i];
  464.          f.name[l]:=#0;
  465.       end;
  466.  
  467.     procedure dossearchrec2searchrec(var f : searchrec);
  468.  
  469.       var
  470.          l,i : longint;
  471.  
  472.       begin
  473.          for i:=0 to 12 do
  474.            if f.name[i]=#0 then
  475.              begin
  476.                 l:=i;
  477.                 break;
  478.              end;
  479.          for i:=11 downto 0 do
  480.            f.name[i+1]:=f.name[i];
  481.          f.name[0]:=chr(l);
  482.       end;
  483.  
  484.     procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  485.  
  486.       procedure _findfirst(path : pchar;attr : word;var f : searchrec);
  487.  
  488.         begin
  489.            asm
  490.               movl 18(%ebp),%edx
  491.               movb $0x1a,%ah
  492.               int $0x21
  493.               movl 12(%esp),%edx
  494.               movzwl 16(%esp),%ecx
  495.               movb $0x4e,%ah
  496.               int $0x21
  497.               jnc LFF
  498.               movw %ax,U_DOS_DOSERROR
  499.            LFF:
  500.            end;
  501.         end;
  502.  
  503.       var
  504.          path0 : array[0..80] of char;
  505.  
  506.       begin
  507.          { kein Fehler }
  508.          doserror:=0;
  509.          strpcopy(path0,path);
  510.          _findfirst(path0,attr,f);
  511.          dossearchrec2searchrec(f);
  512.       end;
  513.  
  514.     procedure findnext(var f : searchRec);
  515.  
  516.       procedure _findnext(var f : searchrec);
  517.  
  518.         begin
  519.            asm
  520.               movl 12(%ebp),%edx
  521.               movb $0x1a,%ah
  522.               int $0x21
  523.               movb $0x4f,%ah
  524.               int $0x21
  525.               jnc LFN
  526.               movw %ax,U_DOS_DOSERROR
  527.            LFN:
  528.            end;
  529.         end;
  530.  
  531.       begin
  532.          { kein Fehler }
  533.          doserror:=0;
  534.          searchrec2dossearchrec(f);
  535.          _findnext(f);
  536.          dossearchrec2searchrec(f);
  537.       end;
  538.  
  539.     procedure swapvectors;
  540.  
  541.       begin
  542.          { tut nichts, DOS-Extender übernimmt das Nötige }
  543.          { normalerweise selber                          }
  544.          { nur aus Kompatibilitätsgründen implementiert  }
  545.       end;
  546.  
  547.     type
  548.        ppchar = ^pchar;
  549.  
  550.     function envs : ppchar;
  551.  
  552.       begin
  553.          asm
  554.             movl _environ,%eax
  555.             leave
  556.             ret
  557.          end ['EAX'];
  558.       end;
  559.  
  560.     function envcount : integer;
  561.  
  562.       var
  563.          hp : ppchar;
  564.  
  565.       begin
  566.          hp:=envs;
  567.          envcount:=0;
  568.          while assigned(hp^) do
  569.            begin
  570.               { doppeltgemopelt, aber übersichtlicher }
  571.               inc(envcount);
  572.               hp:=hp+4;
  573.            end;
  574.       end;
  575.  
  576.     function envstr(index : integer) : string;
  577.  
  578.       var
  579.          i : longint;
  580.          hp : ppchar;
  581.  
  582.       begin
  583.          if (index<=0) or (index>envcount) then
  584.            begin
  585.               envstr:='';
  586.               exit;
  587.            end;
  588.          hp:=envs+4*(index-1);
  589.          envstr:=strpas(hp^);
  590.       end;
  591.  
  592.     function getenv(const envvar : string) : string;
  593.  
  594.       var
  595.          hs,_envvar : string;
  596.          eqpos,i : longint;
  597.  
  598.       begin
  599.          _envvar:=upcase(envvar);
  600.          getenv:='';
  601.          for i:=1 to envcount do
  602.            begin
  603.               hs:=envstr(i);
  604.               eqpos:=pos('=',hs);
  605.               if copy(hs,1,eqpos-1)=_envvar then
  606.                 begin
  607.                    getenv:=copy(hs,eqpos+1,length(hs)-eqpos);
  608.                    exit;
  609.                 end;
  610.            end;
  611.       end;
  612.  
  613.     procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;
  614.       var ext : extstr);
  615.  
  616.       var
  617.          s1 : string;
  618.          p1 : byte;
  619.  
  620.       begin
  621.          { try to find out a extension }
  622.          p1:=pos('.',path);
  623.          if p1>0 then
  624.            begin
  625.               ext:=copy(path,p1,4);
  626.               delete(path,p1,length(path)-p1+1);
  627.            end
  628.          else
  629.            ext:='';
  630.          { get drive name }
  631.          p1:=pos(':',path);
  632.          if p1>0 then
  633.            begin
  634.               dir:=path[1]+':';
  635.               delete(path,1,p1);
  636.            end
  637.          else
  638.            dir:='';
  639.          { split the path and the name, there are no more path informtions }
  640.          { if path contains no backslashes                                 }
  641.          while true do
  642.            begin
  643.               p1:=pos('\',path);
  644.               if p1=0 then
  645.                 break;
  646.               dir:=dir+copy(path,1,p1);
  647.               delete(path,1,p1);
  648.            end;
  649.          name:=path;
  650.       end;
  651.  
  652.     function fexpand(const path : pathstr) : pathstr;
  653.  
  654.       var
  655.          retpath : pathstr;
  656.  
  657.       function get_current_drive : char;
  658.  
  659.         begin
  660.            asm
  661.               movb 0x19,%ah
  662.               int $0x21
  663.               addb $65,%al
  664.               leave
  665.               ret
  666.            end;
  667.         end;
  668.  
  669.       function get_path(drive : byte) : string;
  670.  
  671.         begin
  672.            asm
  673.            end;
  674.         end;
  675.  
  676.       var
  677.          i : longint;
  678.  
  679.       begin
  680.          i:=1;
  681.          { Laufwerk feststellen }
  682.          if (path<>'') and (path[2]=':') then
  683.             begin
  684.                retpath:=upcase(path[1]);
  685.                i:=3;
  686.             end
  687.          else
  688.             retpath:=get_current_drive;
  689.          retpath:=retpath+':';
  690.          if path[i]<>'\' then
  691.            begin
  692.               retpath:=retpath+'\';
  693.               inc(i);
  694.               get_path(ord(retpath[1])-64);
  695.            end;               
  696.          fexpand:=retpath;
  697.       end;
  698.  
  699.      procedure packtime (var d: datetime; var time: longint);
  700.  
  701.        var
  702.           zs: longint;
  703.  
  704.        begin
  705.           time:= -1980;
  706.           time:= time + d.year and 127;
  707.           time:= time shl 4;
  708.           time := time + d.month;
  709.           time:= time shl 5;
  710.           time := time + d.day;
  711.           time:= time shl 16;
  712.           zs := d.hour;
  713.           zs:= zs shl 6;
  714.           zs := zs + d.min;
  715.           zs:= zs shl 5;
  716.           zs := zs + d.sec div 2;
  717.           time := time + zs and 65535;
  718.        end;
  719.  
  720.      procedure unpacktime (time: longint; var d: datetime);
  721.  
  722.        begin
  723.           d.sec:= (time and 31) * 2;
  724.           time:= time shr 5;
  725.           d.min:= time and 63;
  726.           time:= time shr 6;
  727.           d.hour:= time and 31;
  728.           time:= time shr 5;
  729.           d.day:= time and 31;
  730.           time:= time shr 5;
  731.           d.month:= time and 15;
  732.           time:= time shr 4;
  733.           d.year:= time + 1980;
  734.        end;
  735. end.
  736.